using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using AUSRIS.Reports.Extensions.Security.AUSecurityService;
using AUSRIS.Framework.Logging;

namespace AUSRIS.Reports.Extensions.Security.Authentication
{
	/// <summary>
	/// Implementation of IAuthenticationProvider that uses
	/// the AU Portal Sercurity Services
	/// </summary>
	public class AUPortalAuthenticationProvider : IAuthenticationProvider
	{
		#region Private Fields

		private string redirectUrl;
		private string returnUrlParameterName;
		private string systemParameterValue;
		private string serviceUrl;
		private string ticketParameterName;
		private string loginAttemptParameterName;
		private bool enableLoginAttemptLogging;

		#endregion

		#region Public Properties

		public bool EnableLoginAttemptLogging
		{
			get
			{
				return enableLoginAttemptLogging;
			}
			set
			{
				enableLoginAttemptLogging = value;
			}
		}

		public string LoginAttemptParameterName
		{
			get
			{
				return loginAttemptParameterName;
			}
			set
			{
				loginAttemptParameterName = value;
			}
		}

		public string TicketParameterName
		{
			get
			{
				return ticketParameterName;
			}
			set
			{
				ticketParameterName = value;
			}
		}

		public string ServiceUrl
		{
			get
			{
				return serviceUrl;
			}
			set
			{
				serviceUrl = value;
			}
		}

		public string ReturnUrlParameterName
		{
			get
			{
				return returnUrlParameterName;
			}
			set
			{
				returnUrlParameterName = value;
			}
		}

		public string RedirectUrl
		{
			get
			{
				return redirectUrl;
			}
			set
			{
				redirectUrl = value;
			}
		}

		#endregion

		#region IAuthenticationProvider Members

		public string GetUsername(HttpContext context)
		{
			string userName = null;
			if ( context.Request.QueryString[this.TicketParameterName] != null )
			{
				string authTicket = context.Request.QueryString[this.TicketParameterName];
				SecurityEndpointService service = new SecurityEndpointService();
				service.Url = this.ServiceUrl;
				SsoCallbackResponse response = service.verifyTicket(authTicket);
				userName = response.personId;
				if ( !string.IsNullOrEmpty(userName) && this.EnableLoginAttemptLogging && !string.IsNullOrEmpty(this.LoginAttemptParameterName) )
				{
					this.VerifyLoginAttempt(context);
				}
			}
			return userName;
		}

		public string GetRedirectUrl(HttpContext context)
		{
			string requestedUrl = context.Request.Url.ToString();
			string separator = requestedUrl.Contains("?") ? "&" : "?";
			string returnUrl;
			if ( this.EnableLoginAttemptLogging && !string.IsNullOrEmpty(this.LoginAttemptParameterName) )
			{
				string loginAttemptId = CreateLoginAttempt();
				returnUrl = string.Format("{0}{1}{2}={3}&{4}=", requestedUrl, separator, this.LoginAttemptParameterName, loginAttemptId, this.TicketParameterName);
			}
			else
			{
				returnUrl = string.Format("{0}{1}{2}=", requestedUrl, separator, this.TicketParameterName);
			}
			string encodedReturnUrl = context.Server.UrlEncode(returnUrl);
			
			separator = this.RedirectUrl.Contains("?") ? "&" : "?";
			string redirectUrl = string.Format("{0}{1}{2}={3}", this.RedirectUrl, separator, this.ReturnUrlParameterName, encodedReturnUrl);
			return redirectUrl;
		}

		public bool IsUIEnabled
		{
			get
			{
				return false;
			}
		}

		#endregion

		#region Private Methods

		private string CreateLoginAttempt()
		{
			string loginAttemptId = Guid.NewGuid().ToString();
			Log.Info(Log.GetSource(), loginAttemptId);
			return loginAttemptId;
		}

		private void VerifyLoginAttempt(HttpContext context)
		{
			if ( context.Request.QueryString[this.LoginAttemptParameterName] != null )
			{
				string loginAttemptId = context.Request.QueryString[this.LoginAttemptParameterName];
				Log.Info(Log.GetSource(), loginAttemptId);
			}
		}

		#endregion
	}
}
